/*

     This file is part of glstart.

    glstart is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

    glstart is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with Foobar. If not, see <https://www.gnu.org/licenses/>. 
*/

#include <stdio.h>
#include <stdlib.h>
#include "bmp_reader.h"

#ifndef BMP_READER_C
#define BMP_READER_C

void readBMPRowByRow(FILE* fp, BMPFile* bmpf) {
  int bytes_per_pixel = bmpf->dhdr.bits_per_pixel/8;
  int row_size = bytes_per_pixel*bmpf->dhdr.width;
  int row_padding = (4 - (row_size % 4)) % 4;
  int rows_written = 0;
  unsigned char* row = (unsigned char*)malloc(row_size+row_padding);
  unsigned char* p = &bmpf->data[(bmpf->dhdr.height-1)*row_size];
  fseek(fp, bmpf->bhdr.pixel_offset, SEEK_SET);
  while(rows_written < bmpf->dhdr.height) {
    fread(row, row_size+row_padding, 1, fp);
    if(bytes_per_pixel == 3) {
      for(int i=0; i<row_size; i+=bytes_per_pixel) {
        *p = row[i+2]; p++;
        *p = row[i+1]; p++;
        *p = row[i]; p++;
      };
    } else if(bytes_per_pixel == 4) {
      for(int i=0; i<row_size; i+=bytes_per_pixel) {
        *p = row[i+3]; p++;
        *p = row[i+2]; p++;
        *p = row[i+1]; p++;
        *p = row[i]; p++;
      };
    } else {
      printf("Error: don't working with bytes_per_pixel = %d\n", bytes_per_pixel);
      exit(0);
    };
    rows_written++;
    p = p - 2*row_size;
  };
  free(row);
};


BMPFile* loadBMPFile(char* fname) {
  FILE* fp = fopen(fname, "r");
  if(!fp) {
    printf("Can't load file \'%s\'\n", fname);
    return NULL;
  };

  BMPFile* bmp_file = (BMPFile*)malloc(sizeof(BMPFile));
  fread(&bmp_file->bhdr, sizeof(BMPHeader), 1, fp);
  fread(&bmp_file->dhdr, sizeof(DIBHeader), 1, fp);

  int data_size = bmp_file->dhdr.width*bmp_file->dhdr.height*bmp_file->dhdr.bits_per_pixel/8;

  bmp_file->data = (unsigned char*)malloc(data_size);
  readBMPRowByRow(fp, bmp_file);
  fclose(fp);
  return bmp_file;
};

void freeBMPFile(BMPFile* bmp_file) {
  if(bmp_file) {
    if(bmp_file->data)
      free(bmp_file->data);
    free(bmp_file);
  };
};


#endif
